import { message } from "@/utils/message";
import { addDialog } from "@/components/ReDialog";
import type { FormProps, SearchFieldsProps } from "./types";
import { h, onMounted, ref, type Ref, toRaw } from "vue";
import {
  cloneDeep,
  delay,
  deviceDetection,
  getKeyList,
  isArray,
  isEmpty
} from "@pureadmin/utils";
import { useI18n } from "vue-i18n";
import { ElMessageBox } from "element-plus";
import { useRoute } from "vue-router";
import { formatColumnsLabel, formatFormColumns } from "@/utils/viewsPublic";
import exportDataForm from "../form/exportData.vue";
import importDataForm from "../form/importData.vue";
import addOrEdit from "../form/addOrEdit.vue";
// import { resourcesIDCacheApi } from "@/api/common";
import { getFieldsData } from "./index";

export function useBaseTable(
  emit: any,
  tableRef: Ref,
  api: FormProps["api"],
  editForm: FormProps["editForm"],
  tableColumns: FormProps["tableColumns"],
  pagination: FormProps["pagination"],
  resultFormat: FormProps["resultFormat"],
  localeName: FormProps["localeName"],
  tableSearchForm: Ref,
  isSearch: Boolean,
  isPagination: Boolean | number
) {
  const { t, te } = useI18n();
  const formRef = ref();
  const searchFields = ref<SearchFieldsProps>({
    page: 1,
    size: 10,
    ordering: "-created_time"
  });
  const defaultValue = ref({});
  const searchColumns = ref([]);
  const selectedNum = ref(0);
  const dataList = ref([]);
  const loading = ref(true);
  const showColumns = ref([]);
  const route = useRoute();
  const extHasUnfold = ref(false);
  const getParameter = isEmpty(route.params) ? route.query : route.params;

  function handleDelete(row) {
    api.delete({ id: row.id }).then(res => {
      if (res.code === 200) {
        message(t("results.success"), { type: "success" });
        onSearch();
      } else {
        message(`${t("results.failed")}，${res.detail}`, { type: "error" });
      }
    });
  }

  function handleSizeChange(val: number) {
    searchFields.value.page = 1;
    searchFields.value.size = val;
    onSearch();
  }

  function handleCurrentChange(val: number) {
    searchFields.value.page = val;
    onSearch();
  }

  function handleSelectionChange(val) {
    selectedNum.value = val.length;
    emit("selectionChange", getSelectPks);
  }

  function onSelectionCancel() {
    selectedNum.value = 0;
    // 用于多选表格，清空用户的选择
    tableRef.value.getTableRef().clearSelection();
  }

  function getSelectPks(key = "id") {
    const manySelectData = tableRef.value.getTableRef().getSelectionRows();
    return getKeyList(manySelectData, key);
  }

  function handleManyDelete() {
    if (selectedNum.value === 0) {
      message(t("results.noSelectedData"), { type: "error" });
      return;
    }
    api.batchDelete(getSelectPks("id")).then(res => {
      if (res.code === 200) {
        message(t("results.batchDelete", { count: selectedNum.value }), {
          type: "success"
        });
        onSelectionCancel();
        onSearch();
      } else {
        message(`${t("results.failed")}，${res.detail}`, { type: "error" });
      }
    });
  }

  function formatColumns(results, columns) {
    if (results.length > 0) {
      showColumns.value = Object.keys(results[0]);
      cloneDeep(columns).forEach(column => {
        if (
          column?.prop &&
          showColumns.value.indexOf(column?.prop.split(".")[0]) === -1
        ) {
          columns.splice(
            columns.findIndex(obj => {
              return obj.label === column.label;
            }),
            1
          );
        }
      });
    }
  }

  function formatSearchPks(params) {
    Object.keys(params).forEach(key => {
      const value = params[key];
      const pks = [];
      if (isArray(value)) {
        value.forEach(item => {
          if (item.id) {
            pks.push(item.id);
          }
        });
        if (pks.length > 0) {
          params[key] = pks;
        }
      }
    });
  }

  function getFormatLabel(label) {
    if (te(label)) {
      return t(label);
    }
    return label;
  }

  function onSearch(init = false) {
    if (init) {
      pagination.currentPage = searchFields.value.page = 1;
      pagination.pageSize = searchFields.value.size = 10;
    }

    loading.value = true;
    ["created_time", "updated_time"].forEach(key => {
      if (searchFields.value[key]?.length === 2) {
        searchFields.value[`${key}_after`] = searchFields.value[key][0];
        searchFields.value[`${key}_before`] = searchFields.value[key][1];
      } else {
        searchFields.value[`${key}_after`] = "";
        searchFields.value[`${key}_before`] = "";
      }
    });

    //表格不需要分页的情况，设置默认搜索每页最大值为1000
    if (typeof isPagination === "number") {
      searchFields.value.size = isPagination;
    }

    const params = cloneDeep(toRaw(searchFields.value));
    // 该方法为了支持pk多选操作将如下格式 [{pk:1},{pk:2}] 转换为 [1,2]
    formatSearchPks(params);

    api
      .list(params)
      .then(res => {
        if (res.code === 200 && res.data) {
          formatColumns(res.data?.list, tableColumns);
          if (resultFormat && typeof resultFormat === "function") {
            dataList.value = resultFormat(res.data.list);
          } else {
            dataList.value = res.data.list;
          }
          pagination.total = res.data.total;
        } else {
          message(`${t("results.failed")}，${res.error}`, { type: "error" });
        }
        emit("searchEnd", getParameter, searchFields, dataList, res);
        delay(500).then(() => {
          loading.value = false;
        });
      })
      .catch(() => {
        loading.value = false;
      });
  }

  // 数据导出
  function exportData() {
    const pks = getSelectPks();
    addDialog({
      title: t("buttons.export"),
      props: {
        formInline: {
          type: "xlsx",
          range: pks.length > 0 ? "selected" : "all",
          pks: pks
        }
      },
      width: "600px",
      draggable: true,
      fullscreen: deviceDetection(),
      fullscreenIcon: true,
      closeOnClickModal: false,
      contentRenderer: () => h(exportDataForm, { ref: formRef }),
      beforeSure: (done, { options }) => {
        const FormRef = formRef.value.getRef();
        const curData = cloneDeep(options.props.formInline);
        FormRef.validate(valid => {
          if (valid) {
            if (curData.range === "all") {
              api.export(curData);
            } else if (curData.range === "search") {
              searchFields.value["type"] = curData["type"];
              api.export(toRaw(searchFields.value));
            } else if (curData.range === "selected") {
              // resourcesIDCacheApi(curData.pks).then(res => {
              //   curData["spm"] = res.spm;
              //   delete curData.pks;
              //   api.export(curData);
              // });
            }
            done();
          }
        });
      }
    });
  }

  // 数据导入
  function importData() {
    addDialog({
      title: t("buttons.import"),
      props: {
        formInline: {
          action: "create",
          api: api
        }
      },
      width: "600px",
      draggable: true,
      fullscreen: deviceDetection(),
      fullscreenIcon: true,
      closeOnClickModal: false,
      contentRenderer: () => h(importDataForm, { ref: formRef }),
      beforeSure: (done, { options }) => {
        const FormRef = formRef.value.getRef();
        const curData = cloneDeep(options.props.formInline);
        const chores = () => {
          message(t("results.success"), { type: "success" });
          done(); // 关闭弹框
          onSearch(); // 刷新表格数据
        };
        FormRef.validate(valid => {
          if (valid) {
            api.import(curData.action, curData.upload[0].raw).then(res => {
              if (res.code === 200) {
                chores();
              } else {
                message(`${t("results.failed")}，${res.detail}`, {
                  type: "error"
                });
              }
            });
          }
        });
      }
    });
  }

  function openDialog(isAdd = true, row = {}) {
    let title = t("buttons.edit");
    if (isAdd) {
      title = t("buttons.add");
    }
    const rowResult = {};
    Object.keys(editForm?.row ?? {}).forEach(key => {
      const getValue = editForm.row[key];
      if (typeof editForm.row[key] === "function") {
        rowResult[key] = getValue(row, isAdd, dataList.value);
      } else {
        rowResult[key] = getValue;
      }
    });
    const propsResult = {};
    Object.keys(editForm?.props ?? {}).forEach(key => {
      const getValue = editForm.props[key];
      if (typeof editForm.props[key] === "function") {
        propsResult[key] = getValue(row, isAdd, dataList.value);
      } else {
        propsResult[key] = getValue;
      }
    });
    const editFormColumns = ref();
    if (typeof editForm?.columns === "function") {
      editFormColumns.value = editForm.columns({
        row,
        isAdd,
        data: dataList.value
      });
    }
    formatFormColumns(
      { isAdd, showColumns: showColumns.value },
      editFormColumns.value as Array<any>,
      t,
      te,
      localeName
    );
    addDialog({
      title: `${title} ${editForm.title ?? ""}`,
      props: {
        formInline: {
          ...row,
          ...rowResult
        },
        ...propsResult,
        showColumns: showColumns.value,
        columns: editFormColumns.value ?? [],
        formProps: editForm?.formProps ?? {},
        isAdd: isAdd
      },
      width: "40%",
      draggable: true,
      fullscreen: deviceDetection(),
      fullscreenIcon: true,
      closeOnClickModal: false,
      contentRenderer: () => h(editForm.form ?? addOrEdit, { ref: formRef }),
      beforeSure: (done, { options }) => {
        const FormRef = formRef.value.getRef();
        const curData = cloneDeep(options.props.formInline);

        const chores = () => {
          message(t("results.success"), { type: "success" });
          done(); // 关闭弹框
          onSearch(); // 刷新表格数据
        };

        FormRef.validate(valid => {
          if (valid) {
            api.save(curData).then(res => {
              if (res.code == 200) {
                chores();
              } else {
                message(res.error, { type: "error" });
              }
            });
          }
        });
      },
      ...editForm.options
    });
  }

  function onChange(
    switchLoadMap,
    { row, index },
    actKey,
    msg,
    updateApi = null,
    actMsg = null
  ) {
    if (!actMsg) {
      actMsg = row[actKey] === false ? t("labels.disable") : t("labels.enable");
    }
    ElMessageBox.confirm(
      `${t("buttons.operateConfirm", {
        action: `<strong>${actMsg}</strong>`,
        message: `<strong style="color:var(--el-color-primary)">${msg}</strong>`
      })}`,
      {
        confirmButtonText: t("buttons.sure"),
        cancelButtonText: t("buttons.cancel"),
        type: "warning",
        dangerouslyUseHTMLString: true,
        draggable: true
      }
    )
      .then(() => {
        switchLoadMap.value[index] = Object.assign(
          {},
          switchLoadMap.value[index],
          {
            loading: true
          }
        );
        if (!updateApi) {
          updateApi = api.update;
        }
        const data = {};
        data[actKey] = row[actKey];
        updateApi(row.id, data)
          .then(res => {
            if (res.code === 200) {
              message(t("results.success"), { type: "success" });
            } else {
              message(`${t("results.failed")}，${res.detail}`, {
                type: "error"
              });
            }
            switchLoadMap.value[index] = Object.assign(
              {},
              switchLoadMap.value[index],
              {
                loading: false
              }
            );
          })
          .catch(e => {
            row[actKey] === false
              ? (row[actKey] = true)
              : (row[actKey] = false);
            switchLoadMap.value[index] = Object.assign(
              {},
              switchLoadMap.value[index],
              {
                loading: false
              }
            );
            throw e;
          });
      })
      .catch(() => {
        row[actKey] === false ? (row[actKey] = true) : (row[actKey] = false);
      });
  }

  //搜索按钮展开折叠
  function extHasUnflodToggle() {
    //搜索[折叠展开]按钮
    extHasUnfold.value = !extHasUnfold.value;
    //搜索折叠面板高度
    const slotHeight = tableSearchForm.value.scrollHeight + 12;
    /**
     * 过渡动画 参考链接：https://blog.csdn.net/qq_16992475/article/details/129786944
     */
    tableSearchForm.value.style.height =
      (extHasUnfold.value ? slotHeight : 0) + "px";
    tableSearchForm.value.style.paddingTop =
      (extHasUnfold.value ? 12 : 0) + "px";
    tableSearchForm.value.style.paddingBottom =
      (extHasUnfold.value ? 12 : 0) + "px";

    // //table父级整体高度
    // const tableOutDivHeight = tableOutDiv.value.scrollHeight;
    // //表格标题按钮行高度
    // const tableTitleDivHeight = tableTitleDiv.value.scrollHeight;
    // //table高度调整
    // height.value = isOpen.value
    //   ? tableOutDivHeight - slotHeight - tableTitleDivHeight - 70
    //   : height.value + slotHeight;
  }

  onMounted(() => {
    if (isSearch) {
      getFieldsData(api.fields, searchFields, searchColumns, localeName).then(
        () => {
          defaultValue.value = cloneDeep(searchFields.value);
          if (getParameter) {
            const parameter = cloneDeep(getParameter);
            Object.keys(parameter).forEach(param => {
              searchFields.value[param] = parameter[param];
            });
          }
          formatColumnsLabel(tableColumns, t, te, localeName);
          onSearch();
        }
      );
    } else {
      onSearch();
    }
  });

  return {
    t,
    route,
    loading,
    dataList,
    pagination,
    selectedNum,
    showColumns,
    defaultValue,
    searchFields,
    tableColumns,
    searchColumns,
    onChange,
    onSearch,
    exportData,
    importData,
    openDialog,
    getSelectPks,
    handleDelete,
    getFormatLabel,
    handleManyDelete,
    handleSizeChange,
    onSelectionCancel,
    handleCurrentChange,
    handleSelectionChange,
    extHasUnfold,
    extHasUnflodToggle
  };
}
